﻿using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;

namespace System.Runtime.Serialization
{
    /// <summary>
    /// 序列化
    /// </summary>
    public static class SerializationManager
    {
        #region 二进制序列化
        /// <summary>
        /// 二进制序列化
        /// </summary>
        /// <param name="data">要序列化的对象</param>
        /// <returns>byte[]</returns>
        public static byte[] BinarySerialize(this object data)
        {
            var serializer = new BinaryFormatter();
            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, data);
                return stream.GetBuffer();
            }
        }

        /// <summary>
        /// 反序列化二进制对象
        /// </summary>
        /// <typeparam name="T">要二进制反序列成的类型</typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T BinaryDeSerialize<T>(this byte[] data)
        {
            var deserializer = new BinaryFormatter();
            using (var stream = new MemoryStream(data))
            {
                return (T) deserializer.Deserialize(stream);
            }
        }
        #endregion

        #region Soap 序列化
        /// <summary>
        /// Soap 序列化
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] SoapSerialize(object data)
        {
            var serializer = new SoapFormatter();
            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, data);
                return stream.GetBuffer();
            }
        }

        /// <summary>
        /// Soap 反序列化
        /// </summary>
        /// <typeparam name="T">要Soap 反序列化成的类型</typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T SoapDeSerialize<T>(byte[] data) where T : class
        {
            var deserializer = new SoapFormatter();
            using (var stream = new MemoryStream(data))
            {
                return deserializer.Deserialize(stream) as T;
            }
        }
        #endregion

        #region XML序列化
        /// <summary>
        /// XML序列化
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] XmlSerializer(object data)
        {
            var xs = new XmlSerializer(data.GetType());
            using (var stream = new MemoryStream())
            {
                xs.Serialize(stream, data);
                return stream.GetBuffer();
            }
        }
        /// <summary>
        /// XML反序列化
        /// </summary>
        /// <typeparam name="T">要XML反序列化成的类型</typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static T XmlDeSerialize<T>(byte[] data) where T : class
        {
            var xs = new XmlSerializer(typeof(T));
            using (var stream = new MemoryStream(data))
            {
                return xs.Deserialize(stream) as T;
            }
        }
        #endregion

        #region Josn序列化
        /// <summary>
        /// Josn序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string JsonSerializer<T>(T data)
        {
            var serializer = new DataContractJsonSerializer(typeof(T));
            using (var ms = new MemoryStream())
            {
                serializer.WriteObject(ms, data);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

       /// <summary>
       ///  JSON反序列化
       /// </summary>
       /// <typeparam name="T"></typeparam>
       /// <param name="json"></param>
       /// <returns></returns>
       public static T JsonDeserialize<T>(string json)
       {
           var ser = new DataContractJsonSerializer(typeof (T));
           var ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
           var obj = (T) ser.ReadObject(ms);
           return obj;
       }

        #endregion

        #region Bson序列化
       /// <summary>
       /// Bson二进制序列化
       /// </summary>
       /// <param name="data">要序列化的对象</param>
       /// <returns>byte[]</returns>
       public static byte[] BsonSerialize(this object data)
       {
           using (var stream = new MemoryStream())
           {
               var bsonWriter = new BsonWriter(stream);
               var serializer = new JsonSerializer();
               serializer.Serialize(bsonWriter, data);
               return stream.ToArray();
           }
       }

       /// <summary>
       /// Bson反序列化二进制对象
       /// </summary>
       /// <typeparam name="T">要Bson反序列成的类型</typeparam>
       /// <param name="data"></param>
       /// <returns></returns>
       public static T BsonDeSerialize<T>(this byte[] data)
       {
           using (var stream = new MemoryStream(data))
           {
               var reader = new BsonReader(stream);
               if (typeof(ICollection).IsAssignableFrom(typeof(T)))
               {
                   reader.ReadRootValueAsArray = true;
               }
               var serializer = Newtonsoft.Json.JsonSerializer.Create(null);
               return serializer.Deserialize<T>(reader);
           }
       }
        #endregion
    }
}
